# 导入必要的库
import base64
import ctypes
import os
import sys
import tkinter as tk
from tkinter import messagebox
from app.init_var import InitVar
from app.view.app_view import AppView


def check_single_instance():
    """检查是否已经有实例在运行"""
    mutex_name = "RandomImageViewer_Mutex"  # 唯一标识符
    mutex = ctypes.windll.kernel32.CreateMutexW(None, False, mutex_name)
    last_error = ctypes.windll.kernel32.GetLastError()

    return mutex, last_error == 183  # ERROR_ALREADY_EXISTS


def bring_to_front(window):
    """将窗口带到前台"""
    window.attributes('-topmost', 1)
    window.attributes('-topmost', 0)
    window.lift()
    window.focus_force()


if __name__ == "__main__":
    if os.name != 'nt':
        messagebox.showerror("错误", "当前程序仅支持Windows系统。")
        sys.exit()

    # 检查是否已有实例运行
    mutex, already_running = check_single_instance()

    if already_running:
        # 查找已有窗口并带到前台
        hwnd = ctypes.windll.user32.FindWindowW(None, InitVar.WINDOW_TITLE)
        if hwnd:
            # 恢复最小化的窗口
            ctypes.windll.user32.ShowWindow(hwnd, 9)  # SW_RESTORE = 9
            # 激活窗口
            ctypes.windll.user32.SetForegroundWindow(hwnd)
        messagebox.showinfo("提示", "程序已经在运行中。")
        sys.exit()

    try:
        # 设置设置当前进程显式应用程序用户模型ID
        ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID("RandomImageViewer")
        root = tk.Tk()

        # 初始窗口标题
        root.title(InitVar.WINDOW_TITLE)

        # 设置程序ICO
        # 读取Base64转成ICO文件
        icon_bytes = base64.b64decode(InitVar.ICO_)
        # 保存为临时 ICO 文件
        temp_icon_path = "temp_icon.ico"
        with open(temp_icon_path, "wb") as icon_file:
            icon_file.write(icon_bytes)
        root.iconbitmap(temp_icon_path)  # 设置程序ICO
        # 删除临时 ICO 文件
        os.remove(temp_icon_path)

        # 设置全局字体为微软雅黑
        default_font = ("微软雅黑", 12)
        root.option_add("*Font", default_font)
        # 将窗体对象传入主视图
        app_view = AppView(root)
        root.mainloop()
    finally:
        # 释放互斥锁
        if mutex:
            ctypes.windll.kernel32.CloseHandle(mutex)